package interview;


// Java面试题全集（上）


/*
1. 面向对象的特征有哪些方面？
抽象、继承、封装、多态
封闭开放。
 */


/*
2. 访问修饰符public,private,protected,以及不写（默认）时的区别？
任何声明为public的内容可以被从任何地方访问。被声明成private的成员不能被该类
外看到。如果一个成员不含有一个明确的访问说明，它对于子类或该包中的其他类是可见
的。这是默认访问。如果你希望一个元素在当前包外可见，但仅仅是元素所在类的子类直
接可见，把元素定义成protected。
 */


/*
3. String是最基本的数据类型吗？
不是。Java中的基本数据类型只有8个：byte、short、int、long、float、double、
char、boolean；除了基本类型（primitive type）和枚举类型（enumeration type），
剩下的都是引用类型（reference type）。
 */


/*
4. float f = 3.4;是否正确？
不正确。
3.4是双精度数，将双精度型（double）赋值给浮点型（float）属于下转型
（down-casting，也称为窄化）会造成精度损失，因此需要强制类型转换
float f =(float)3.4; 或者写成float f =3.4F;。
 */


/*
5. short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗？
对于short s1 = 1; s1 = s1 + 1;由于1是int类型，因此s1+1运算结果也是int 型，
需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译，
因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
 */


/*
6. Java有没有goto？
goto 是Java中的保留字，在目前版本的Java中没有使用。（根据James Gosling
（Java之父）编写的《The Java Programming Language》一书的附录中给出了一个
Java关键字列表，其中有goto和const，但是这两个是目前无法使用的关键字，因此有
些地方将其称之为保留字。
 */


/*
7. int和Integer有什么区别？
Java是一个近乎纯洁的面向对象编程语言，但是为了编程的方便还是引入了基本数据类型，
但是为了能够将这些基本数据类型当成对象操作，Java为每一个基本数据类型都引入了对
应的包装类型（wrapper class），int的包装类就是Integer，从Java 5开始引入了自
动装箱/拆箱机制，使得二者可以相互转换。
 */


public class QuestionOne {

    static void foo4() {
        float f = (float) 3.4;
    }

    static void foo5() {
        short s1 = 1;
        s1 = (short) (s1 + 1);
    }

    static void foo7() {
        Integer a = new Integer(3);
        Integer b = 3;                  // 将3自动装箱成Integer类型
        int c = 3;
        System.out.println(a == b);     // false 两个引用没有引用同一对象
        System.out.println(a == c);     // true a自动拆箱成int类型再和c比较
    }

    static void foo7_2() {
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
        System.out.println(f1 == f2);
        System.out.println(f3 == f4);
        /*
        装箱的本质是什么呢？当我们给一个Integer对象赋一个int值的时候，会调用
        Integer类的静态方法valueOf。
        如果整型字面量的值在-128到127之间，那么不会new新的Integer对象，而是直接引用
        常量池中的Integer对象。所以f1==f2的结果是true，而f3=f4的结果是false。
         */
    }

    /*
    8. &和&&的区别？
    &运算符有两种用法：（1）按位与；（2）逻辑与。&&运算符是短路与运算。
    逻辑与跟短路与的差别是非常巨大的，虽然二者都要求运算符左右两端的布尔值都是
    true整个表达式的值才是true。&&之所以称为短路运算是因为，如果&&左边的表达
    式的值是false，右边的表达式会被直接短路掉，不会进行运算。
     */

    /*
    9. 解释内存中栈、堆和静态区的用法。
    通常我们定义一个基本数据类型的变量，一个对象的引用，还有就是函数调用的现场保存
    都使用内存中的栈空间；而通过new关键字和构造器创建的对象放在堆空间；程序中的字
    面量（literal）如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来
    最快但是栈很小，通常大量的对象都是放在堆空间，理论上整个内存没有被其他进程使用
    的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。
    String str = new String("hello");
    上面的语句中变量str放在栈上，用new创建出来的字符串对象放在堆上，而”hello”这个
    字面量放在静态区。
     */

    /*
    10. Math.round(11.5)等于多少？Math.round(-11.5)等于多少？
    Math.round(11.5)的返回值是12，Math.round(-11.5)的返回值是-11。四舍五入的
    原理是在参数上加0.5然后进行下取整。
     */

    /*
    11. switch是否能作用在byte上，是否能作用在long上，是否能作用在String上？
    在Java 5以前，switch(expr)中，expr只能是byte、short、char、int。从Java 5开始，
    Java中引入了枚举类型，expr也可以是enum类型，从Java 7开始，expr还可以是
    字符串（String），但是长整型（long）在目前所有的版本中都是不可以的。
     */

    /*
    12. 用最有效率的方法计算2乘以8？
    2 << 3（左移3位相当于乘以2的3次方，右移3位相当于除以2的3次方）。
     */

    /*
    13. 数组有没有length()方法？String有没有length()方法？
    数组没有length()方法，有length属性。String有length()方法。
     */

    /*
    14. 在Java中，如何跳出当前的多重嵌套循环？
    在最外层循环前加一个标记如A，然后用break A;可以跳出多重循环。（Java中支持带标签的
    break和continue语句，作用有点类似于C和C++中的goto语句，但是就像要避免使用goto一样，
    应该避免使用带标签的break和continue，因为它不会让你的程序变得更优雅，很多时候甚至
    有相反的作用，所以这种语法其实不知道更好）
     */

    /*
    15. 构造器（constructor）是否可以被重写（overide）？
    构造器不能被继承，因此不能被重写，但可以被重载。
     */

    /*
    16. 两个对象值相同（x.equals(y) == true），但却可有不同的hash code，这句话对不对？
    不对，如果两个对象x和y满足x.equals(y) == true，它们的哈希码（hash code）应当相同。
    Java对于eqauls方法和hashCode方法是这样规定的：(1)如果两个对象相同（equals方法返回
    true），那么它们的hashCode值一定要相同；(2)如果两个对象的hashCode相同，它们并不一定
    相同。当然，你未必要按照要求去做，但是如果你违背了上述原则就会发现在使用容器时，相同的
    对象可以出现在Set集合中，同时增加新元素的效率会大大下降（对于使用哈希存储的系统，如果
    哈希码频繁的冲突将会造成存取性能急剧下降）。
     */


    public static void main(String[] args) {
//        foo4();
//        foo7();
        foo7_2();
    }
}
